package com.lizemin.mybatis.annotation;

import cn.hutool.core.util.ClassUtil;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * @author lzm
 * @date 2025/5/18 21:32
 * @description
 */
public class PowerMybatisMapperScan implements ImportBeanDefinitionRegistrar {


    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        // 获取注解属性
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(EnableMybatis.class.getName()));
        if (attributes != null) {
            String[] basePackages = attributes.getStringArray("basePackages");
            if (basePackages.length == 0) {
                basePackages = new String[]{ClassUtils.getPackageName(importingClassMetadata.getClassName())};
            }
            HashSet<Class<?>> interfaces = new HashSet<>();
            for (String basePackage : basePackages) {
                Set<Class<?>> classes = ClassUtil.scanPackage(basePackage, Class::isInterface);
                interfaces.addAll(classes);
            }
            // 为每个接口生成代理对象并注册到 Spring 容器
            for (Class<?> interfaceClass : interfaces) {
                registerProxyBean(interfaceClass, registry);
            }
        }

    }

    private void registerProxyBean(Class<?> interfaceClass, BeanDefinitionRegistry registry) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(ProxyBeanFactory.class);
        beanDefinition.setFactoryMethodName("getProxy"); //工厂方法，类似于@bean注解标记的方法
        beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(interfaceClass);
        registry.registerBeanDefinition(interfaceClass.getSimpleName(), beanDefinition);
    }

}
